<#include "rules.fm">

<#assign emma=.node.project["emma-filters"]?size!=0>
<#assign findbugs=.node.project["findbugs"]?size!=0>
<#assign checkstyle=.node.project["checkstyle-config"]?size!=0>
<#assign pmd=.node.project["pmd-ruleset"]?size!=0>

<project name="${.node.project.@name}" basedir="." default="main">

	<target name="init">
		<tstamp>
			<format property="build.start" pattern="dd-MMM-yyyy hh:mm:ss aa"/>
		</tstamp>
	</target>
	
<#if emma>
	<property name="emma.home" value="${r'${packages.home}'}/emma-2.0.5312"/>

	<path id="emma.classpath">
		<path location="${r'${emma.home}'}/lib/emma.jar"/>
		<path location="${r'${emma.home}'}/lib/emma_ant.jar"/>
	</path>

	<taskdef resource="emma_ant.properties" classpathref="emma.classpath"/>
</#if>
	
<#list .node.project["modules-to-build"].module as module>
	<!-- 
	  Build targets for module ${module.@name} 
	-->

<#if hasFacet(module, 'java')>
	<path id="${module.@name}.classpath">
<#list module.dependencies["exposed-dependencies"].dependency as dependency>
<#if dependency.@type = "library">
<#list dependency.path as path>
				<path location="${r'${'}${dependency.@library}.home${r'}'}/${path.@location}"/>
</#list>	
<#elseif dependency.@type = "module">
				<path location="${r'${output.dir}'}/modules/${dependency.@module}/classes"/>
<#elseif dependency.@type = "archive">
				<path location="<@archivepath dependency.@archive/>"/>
<#elseif dependency.@type = "archivegroup">
<#list dependency.path as path>
				<path location="<@archivepath path.@location/>"/>
</#list>	
</#if>
</#list>	
	</path>

	<target name="${module.@name}.compile">
		<mkdir dir="${r'${output.dir}'}/modules/${module.@name}/classes"/>
		<javac destdir="${r'${output.dir}'}/modules/${module.@name}/classes" debug="yes" failonerror="yes">
			<src path="${module.basedir}/src"/>  
			<classpath refid="${module.@name}.classpath"/>
		</javac>
		<copy todir="${r'${output.dir}'}/modules/${module.@name}/classes">
			<fileset dir="${module.basedir}/src">
				<exclude name="**/*.java"/>
				<exclude name="**/*.jj"/>
				<exclude name="**/log4j.properties"/>
			</fileset>
		</copy>
	</target>

<#if pmd>
	<target name="${module.@name}.pmd">
		<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask">
			<classpath>
				<path location="${r'${packages.home}'}/pmd-3.9/lib/pmd-3.9.jar"/>
			</classpath>
		</taskdef>
		<pmd targetjdk="1.6" failuresPropertyName="${module.@name}.pmd-error" failonerror="true" failOnRuleViolation="false">
			<ruleset>${.node.project["pmd-ruleset"]}</ruleset>
			<formatter type="html" toFile="${r'${output.dir}'}/modules/${module.@name}/pmd.html" toConsole="false"/>
			<fileset dir="${module.basedir}/src">
				<include name="**/*.java"/>
			</fileset>
		</pmd>
	</target>
</#if>

<#if findbugs>
	<target name="${module.@name}.findbugs">
		<property name="findbugs.home" value="${r'${packages.home}'}/findbugs-1.1.3"/>
		<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
			<classpath>
				<path location="${r'${findbugs.home}'}/lib/findbugs-ant.jar"/>
			</classpath>
		</taskdef>

		<findbugs home="${r'${findbugs.home}'}"
			  output="html"
			  outputFile="${r'${output.dir}'}/modules/${module.@name}/findbugs.html"
			  failOnError="true" errorProperty="${module.@name}.findbugs-error">
			  
			<sourcePath path="${module.basedir}/src"/>
			<class location="${r'${output.dir}'}/modules/${module.@name}/classes"/>
<#if module.dependencies["exposed-dependencies"].dependency?size!=0>
			<auxClasspath refid="${module.@name}.classpath"/>
</#if>
		</findbugs>
		<replace file="${r'${output.dir}'}/modules/${module.@name}/findbugs.html">
			<replacetoken><![CDATA[&lt;&lt;unnamed project&gt;&gt;]]></replacetoken> 
			<replacevalue>${module.@name}</replacevalue>
		</replace>
	</target>
</#if>

<#if checkstyle>
	<target name="${module.@name}.checkstyle">
		<property name="checkstyle.home" location="${r'${packages.home}'}/checkstyle-4.3"/>
		<taskdef resource="checkstyletask.properties" classpath="${r'${checkstyle.home}'}/checkstyle-all-4.3.jar"/>
		
		<checkstyle config="${.node.project["checkstyle-config"]}"
			    failureProperty="${module.@name}.checkstyle-error"
			    failOnViolation="false">
			<fileset dir="${module.basedir}/src">
				<include name="**/*.java"/>
			</fileset>
			<formatter type="plain" toFile="${r'${output.dir}'}/modules/${module.@name}/checkstyle.txt"/>
			<formatter type="xml" toFile="${r'${output.dir}'}/modules/${module.@name}/checkstyle.xml"/>
		</checkstyle>
	</target>
</#if>
</#if> <#-- facet -->

<#if hasFacet(module, 'test')>
	<path id="${module.@name}.test-compile.classpath">
				<path location="${r'${output.dir}'}/modules/${module.@name}/classes"/>
<#list module.dependencies["exposed-dependencies"].dependency as dependency>
<#if dependency.@type = "library">
<#list dependency.path as path>
				<path location="${r'${'}${dependency.@library}.home${r'}'}/${path.@location}"/>
</#list>	
<#elseif dependency.@type = "module">
				<path location="${r'${output.dir}'}/modules/${dependency.@module}/classes"/>
				<path location="${r'${output.dir}'}/modules/${dependency.@module}/test-classes"/>
<#elseif dependency.@type = "archive">
				<path location="<@archivepath dependency.@archive/>"/>
<#elseif dependency.@type = "archivegroup">
<#list dependency.path as path>
				<path location="<@archivepath path.@location/>"/>
</#list>	
</#if>
</#list>
	</path>
	
	<target name="${module.@name}.test-compile">
		<mkdir dir="${r'${output.dir}'}/modules/${module.@name}/test-classes"/>
		<javac destdir="${r'${output.dir}'}/modules/${module.@name}/test-classes" debug="yes" failonerror="yes">
			<src path="${module.basedir}/test"/>
			<classpath refid="${module.@name}.test-compile.classpath"/>
		</javac>
		<copy todir="${r'${output.dir}'}/modules/${module.@name}/test-classes">
			<fileset dir="${module.basedir}/test">
				<exclude name="**/*.java"/>
			</fileset>
		</copy>
	</target>
	
	<path id="${module.@name}.test.classpath">
				<path location="${r'${output.dir}'}/modules/${module.@name}/classes"/>
				<path location="${r'${output.dir}'}/modules/${module.@name}/test-classes"/>
<#list module.dependencies["all-dependencies"].dependency as dependency>
<#if dependency.@type = "library">
<#list dependency.path as path>
				<path location="${r'${'}${dependency.@library}.home${r'}'}/${path.@location}"/>
</#list>	
<#elseif dependency.@type = "module">
				<path location="${r'${output.dir}'}/modules/${dependency.@module}/classes"/>
				<path location="${r'${output.dir}'}/modules/${dependency.@module}/test-classes"/>
<#elseif dependency.@type = "archive">
				<path location="<@archivepath dependency.@archive/>"/>
<#elseif dependency.@type = "archivegroup">
<#list dependency.path as path>
				<path location="<@archivepath path.@location/>"/>
</#list>	
</#if>
</#list>
	</path>		
	
<#if emma>
	<target name="${module.@name}.emma">
		<property name="emma.enabled" value="true"/>
		<property name="out.instr.dir" location="${r'${output.dir}'}/modules/${module.@name}/outinstr"/>
		<mkdir dir="${r'${out.instr.dir}'}"/>
	</target>
</#if>	

	<target name="${module.@name}.test">

<#if emma>
		<emma enabled="${r'${emma.enabled}'}">
			<instr instrpathref="${module.@name}.test.classpath"
			       destdir="${r'${out.instr.dir}'}"
			       metadatafile="${r'${output.dir}'}/modules/${module.@name}/metadata.emma"
			       merge="true">
				<filter file="${.node.project["emma-filters"]}"/>
			</instr>
		</emma>
</#if>
		
		<mkdir dir="${r'${output.dir}'}/modules/${module.@name}/junit-xml-reports"/>
		<junit printsummary="on" fork="yes" dir="${r'${output.dir}'}/modules/${module.@name}" haltonfailure="no" failureproperty="${module.@name}.test-failure" errorproperty="${module.@name}.test-error">
			<classpath> 
				<path location="${r'${out.instr.dir}'}"/>
				<path refid="${module.@name}.test.classpath"/>
				<#if emma><path refid="emma.classpath"/></#if><#t>
			</classpath>

			<formatter type="xml"/>
			<batchtest todir="${r'${output.dir}'}/modules/${module.@name}/junit-xml-reports">
				<fileset dir="${module.basedir}/test">
					<include name="**/*Test.java"/>
				</fileset>
			</batchtest>
<#if emma>
			<jvmarg value="-Demma.coverage.out.file=${r'${output.dir}'}/modules/${module.@name}/coverage.emma"/>
			<jvmarg value="-Demma.coverage.out.merge=true"/>
</#if>
		</junit>
		
<#if emma>
		<emma enabled="${r'${emma.enabled}'}">
			<report sourcepath="${module.basedir}/src">
				<fileset dir="${r'${output.dir}'}/modules/${module.@name}">
					<include name="*.emma"/>
				</fileset>

				<txt outfile="${r'${output.dir}'}/modules/${module.@name}/emma_coverage.txt"/>
				<html outfile="${r'${output.dir}'}/modules/${module.@name}/emma_coverage.html"/>
			</report>
		</emma>
</#if>
		
		<mkdir dir="${r'${output.dir}'}/modules/${module.@name}/junit-html-reports/frames"/>
		<mkdir dir="${r'${output.dir}'}/modules/${module.@name}/junit-report"/>
		<junitreport todir="${r'${output.dir}'}/modules/${module.@name}/junit-report">
			<fileset dir="${r'${output.dir}'}/modules/${module.@name}/junit-xml-reports">
				<include name="TEST-*.xml"/>
			</fileset>
			<report format="frames" todir="${r'${output.dir}'}/modules/${module.@name}/junit-html-reports/frames"/>
		</junitreport>
		
		<copy todir="${r'${output.dir}'}/reports/junit-xml-reports">
			<fileset dir="${r'${output.dir}'}/modules/${module.@name}/junit-xml-reports">
				<include name="TEST-*.xml"/>
			</fileset>
		</copy>
	</target>

</#if>

<#macro moduleDeps module>
<#if hasFacet(module, 'java') && hasFacet(module, 'test')>${module.@name}.compile, ${module.@name}.test-compile<#if emma>, ${module.@name}.emma</#if>, ${module.@name}.test<#if pmd>, ${module.@name}.pmd</#if><#if findbugs>, ${module.@name}.findbugs</#if><#if checkstyle>, ${module.@name}.checkstyle</#if><#t>
<#elseif hasFacet(module, 'java')>${module.@name}.compile<#if pmd>, ${module.@name}.pmd</#if><#if findbugs>, ${module.@name}.findbugs</#if><#if checkstyle>, ${module.@name}.checkstyle</#if><#t>
<#elseif hasFacet(module, 'test')>${module.@name}.test-compile<#if emma>, ${module.@name}.emma</#if>, ${module.@name}.test<#t>
</#if>
</#macro>

	<target name="${module.@name}" depends="<@moduleDeps module/>"/>

</#list>

	<target name="consolidated-reports">
		<mkdir dir="${r'${output.dir}'}/reports/junit-report"/>
		<mkdir dir="${r'${output.dir}'}/reports/junit-html-reports/frames"/>
		<mkdir dir="${r'${output.dir}'}/reports/junit-xml-reports"/>
		<junitreport todir="${r'${output.dir}'}/reports/junit-report">
			<fileset dir="${r'${output.dir}'}/reports/junit-xml-reports">
				<include name="TEST-*.xml"/>
			</fileset>
			<report format="frames" todir="${r'${output.dir}'}/reports/junit-html-reports/frames"/>
		</junitreport>
	</target>

	<target name="copy-src">
		<copy todir="${r'${output.dir}'}/project/src">

<#list .node.project["modules-to-build"].module as module>
<#if hasFacet(module,'java')>
			<fileset dir="${module.basedir}/src"/>
</#if>
</#list>
		</copy>
	</target>

	<target name="javadoc" depends="copy-src">
		<mkdir dir="${r'${output.dir}'}/staging/docs/api"/>
		<javadoc
		   		destdir="${r'${output.dir}'}/staging/docs/api"
		   		author="true"
		   		version="true"
		   		use="true"
		   		windowtitle="${.node.project.@name} API - version ${.node.project.version}" >

				<fileset dir="${r'${output.dir}'}/project/src" defaultexcludes="yes">
	  				<include name="**/*.java"/>
				</fileset>

			<classpath>
<#list .node.project["modules-to-build"].module as module>
<#list module.dependencies["direct-dependencies"].dependency as dependency>
<#if dependency.@type = "library">
<#list dependency.path as path>
				<path location="${r'${'}${dependency.@library}.home${r'}'}/${path.@location}"/>
</#list>	
<#elseif dependency.@type = "archive">
				<path location="<@archivepath dependency.@archive/>"/>
<#elseif dependency.@type = "archivegroup">
<#list dependency.path as path>
				<path location="<@archivepath path.@location/>"/>
</#list>	
</#if>
</#list>
</#list>
			</classpath>

   			<doctitle><![CDATA[<h1>${.node.project.@name} - ${.node.project.version}</h1>]]></doctitle>
   			<bottom><![CDATA[<i>Copyright &#169; 2007, Malcolm Sparks. All Rights Reserved.</i>]]></bottom>
  		</javadoc>
	</target>
	
	<target name="distribution">
		<mkdir dir="${r'${output.dir}'}/staging/lib"/>

		<#list .node.project.deployment.jars.jar as jar>
		<!-- Cannot compress due to problems in Java 6 and jar corruptions. If this is an old comment, and Java build is higher than 1.6.0b106, try removing the compress attribute -->
		<jar destfile="${r'${output.dir}'}/staging/lib/${jar.@name}" duplicate="fail" compress="false">
		<#list jar.module as module>
			<fileset dir="${r'${output.dir}'}/modules/${module.@name}/classes"/>
		</#list>
		</jar>
		</#list>

		<copy todir="${r'${output.dir}'}/staging">
			<fileset dir="${r'${output.dir}'}/project">
				<include name="src/"/>
			</fileset>
		</copy>

	</target>
	
	<target name="export">
		<property name="export.dir" value="${r'${packages.home}'}/${.node.project.@export}-${.node.project.version}"/>
		<delete dir="${r'${export.dir}'}" quiet="yet" includeEmptyDirs="yes"/>
		<copy todir="${r'${export.dir}'}">
			<fileset dir="${r'${output.dir}'}/staging"/>
		</copy>
	</target>

	<target name="end">
		<tstamp>
			<format property="build.end" pattern="dd-MMM-yyyy hh:mm:ss aa"/>
		</tstamp>
	</target>


<#macro projects>
<#list .node.project["modules-to-build"].module as module>${module.@name}<#if module_has_next>, </#if></#list><#t>
</#macro>

<#macro normalDeps>
init, <@projects/>, consolidated-reports, compute-failures, end, fail-on-failures<#t>
</#macro>

<#--
<#macro normalDeps>
init<#t>
</#macro>
-->

<#-- Only do these if the build and tests are all OK -->
<#macro onTestSuccessDeps>
javadoc, distribution<#t>
</#macro>

	<target name="nothing"/>

	<target name="main" depends="<@normalDeps/>, <@onTestSuccessDeps/>"/>

	<target name="compute-failures">
<#list .node.project["modules-to-build"].module as module>
		<condition property="${module.@name}.unit-tests-failed">
			<or>
				<isset property="${module.@name}.test-failure"/>
				<isset property="${module.@name}.test-error"/>
			</or>
		</condition>
</#list>

<#if pmd>
<#list .node.project["modules-to-build"].module as module>
		<condition property="${module.@name}.pmd-failed">
			<or>
				<isset property="${module.@name}.pmd-error"/>
			</or>
		</condition>
</#list>
</#if>

<#if findbugs>
<#list .node.project["modules-to-build"].module as module>
		<condition property="${module.@name}.findbugs-failed">
			<or>
				<isset property="${module.@name}.findbugs-error"/>
			</or>
		</condition>
</#list>
</#if>

<#if checkstyle>
<#list .node.project["modules-to-build"].module as module>
		<condition property="${module.@name}.checkstyle-failed">
			<or>
				<isset property="${module.@name}.checkstyle-error"/>
			</or>
		</condition>
</#list>
</#if>
	</target>

	<target name="fail-on-failures">
<#list .node.project["modules-to-build"].module as module>
		<fail if="${module.@name}.unit-tests-failed" message="Some unit tests in ${module.@name} failed"/>
</#list>
<#list .node.project["modules-to-build"].module as module>
		<fail if="${module.@name}.pmd-failed" message="PMD violations in ${module.@name}"/>
</#list>
<#if findbugs>
<#list .node.project["modules-to-build"].module as module>
		<fail if="${module.@name}.findbugs-failed" message="Findbugs errors in ${module.@name}"/>
</#list>
</#if>

<#if checkstyle>
<#list .node.project["modules-to-build"].module as module>
		<fail if="${module.@name}.checkstyle-failed" message="Checkstyle errors in ${module.@name}"/>
</#list>
</#if>

	</target>

</project>
